import React, { Component } from 'react';

class Index extends Component {
    state = {
        val1: '111',
    }
    render() {
        return (
            <div >
                <button onClick={() => {this.setState({val1:Math.random()})}}>修改val1</button>
                <Child1 {...this.state}/>
                <Child2 {...this.state}/>
                {/* <Child3 {...this.state}/> */}
            </div>
        );
    }
}

export default Index;

class Child1 extends Component {
    state = {
        value1: '111'
    }
    // 子组件监听父组件props的变化，来更新子组件自己的状态，子组件内部也可以修改自己的状态
    componentDidUpdate (prevProps) {
        if (this.props.val1 !== prevProps.val1) {
            this.setState({value1: this.props.val1}) // render执行完毕后，会重新调用componentDidUpdate
        }
    }
    render() {
        let {value1} = this.state
        return (
            <div >
                子组件1
                <div>组件监听父组件props的变化，来更新子组件自己的状态，子组件内部也可以修改自己的状态</div>
                <input value={value1} onChange={(e)=>{this.setState({value1:e.target.value})}} type="text" />
            </div>
        );
    }
}

class Child2 extends Component {
    state = {
        value1: '111'
    }
    // getDerivedStateFromProps 使子组件状态取决于父组件传递的值，子组件内部不能修改自己的状态
    static getDerivedStateFromProps ({val1},state) {
        // 
        return {value1:val1}
    }
    render() {
        let {value1} = this.state
        return (
            <div >
                子组件2(完全取决于父组件val1的值)
                <div>使用getDerivedStateFromProps实现子组件内部不能修改自己的状态</div>
                <input value={value1} onChange={(e)=>{
                    // 虽然在此更新了state，但从声明周期上来看，在getDerivedStateFromProps钩子中会再次修改state
                    console.warn('更新state')
                    this.setState({value1:e.target.value})
                }} type="text" />
            </div>
        );
    }
}
class Child3 extends Component {
    state = {
        value1: '111',
        value2: '111',
    }
    // getDerivedStateFromProps 使子组件状态取决于父组件传递的值，子组件内部不能修改自己的状态
    static getDerivedStateFromProps ({val1},state) {
        // 有条件的控制state
        if (val1 != state.value1) {
            return {value1:val1}
        }
        return null
    }
    render() {
        let {value1,value2} = this.state
        return (
            <div >
                子组件3
                <div>使用getDerivedStateFromProps 实现子组件状态取决于父组件传递的值</div>
                <input value={value1} onChange={(e)=>{
                    this.setState({value1:e.target.value})
                }} type="text" />
                <input value={value2} onChange={(e)=>{
                    this.setState({value2:e.target.value})
                }} type="text" />
            </div>
        );
    }
}